Skip to content

Initial Numba support#626

Merged
knoepfel merged 46 commits into
Framework-R-D:mainfrom
wlav:numba-support
Jun 27, 2026
Merged

Initial Numba support#626
knoepfel merged 46 commits into
Framework-R-D:mainfrom
wlav:numba-support

Conversation

@wlav

@wlav wlav commented Jun 2, 2026

Copy link
Copy Markdown
Contributor

This PR adds "native" Numba support to phlex.

Numba was usable out-of-the-box already, through Python, but even if the Numba function itself didn't use the GIL, it still needed it at the start of every call (through the wrapper) and all Python/C++ converters required them, too. The implementation in this PR allows for calling the Numba JITed C-function directly, using converters that do not involve Python, and a dispatch through libffi. That sets up a workflow that doesn't require the GIL anywhere beyond configuration/registration time, thus enabling strong scaling (as far as Phlex is concerned) during graph execution.

This PR is for transforms only (observers and providers to follow) and only supports builtin types. Arrays and PODs (by member copy) should be doable as well, but Numba does not support arbitrary C++ classes.

The code in the module wrapper was significantly refactored, to maximize code reuse.

Note: it requires libffi, which will be available on most Linux boxes, but probably needs to be installed with spack in other places, so the spack recipe would need updating as well.

Build system

  • Updated plugins/python/CMakeLists.txt to locate libffi via PkgConfig (pkg_check_modules(FFI ...) using PkgConfig::FFI) and link it into the pymodule target.
  • Added plugins/python/src/dyncall.cpp (and its companion header plugins/python/src/dyncall.hpp) to the pymodule build.

Numba/libffi native call support (core feature)

  • Implemented libffi-based dynamic calling to invoke Numba JIT-compiled C functions directly:
    • Added phlex::experimental::dcarg (type-erased std::variant container) and phlex::experimental::dcargs_t.
    • Added dcarg::from_str() to construct supported argument/return payloads from a fixed set of type-name strings (bool, int/uint variants, ph_long_t/ph_ulong_t, float/double, void/null), throwing on unsupported types.
    • Added dcarg::value_ptr() plus internal ffi type mapping and a phlex::experimental::dyncall() implementation that builds ffi_cif/argument metadata at runtime and calls via ffi_call.
  • Added conditional Numba-aware type mappings in plugins/python/python/phlex/_typing.py:
    • Conditionally imports numba.core.types and extends Python→C++ scalar mapping with Numba scalar types.
    • Adds explicit "float32" → "float" and "float64" → "double" handling (alongside existing long long/unsigned long long special cases).

Python module wrapper + graph wiring refactor (transforms)

  • Refactored plugins/python/src/modulewrap.cpp to maximize code reuse and route dispatch through dcarg/dyncall:
    • Replaced prior callback/value plumbing with py_callback_base / py_callback_impl / jit_callback_impl using dcarg.
    • Added detection of Numba CFunc and dispatch selection between Python-callback path vs JIT (Numba) function-pointer path.
    • Added/kept an unrolled selector-based wiring path supporting up to 1–3 inputs (unroll_switch).
    • Passed transform concurrency through converter/dispatch wiring (so converter nodes receive nconcur).
    • Updated argument parsing and selector plumbing to use selector dictionaries (input_selectors) rather than query-based validation.
    • Updated output validation in md_observe/sc_provide to validate selector dictionaries via the selector-based validation path.
  • Converter refactor to avoid Python in the conversion path:
    • Updated converter-generation macros so converters produce/consume dcarg values (including explicit null handling).

Scope and type limitations

  • Implemented for transforms only (observers/providers planned later).
  • Supports builtin scalar types only.
  • Arrays/PODs copied by member are called out as potential future work; arbitrary C++ classes remain unsupported due to Numba limitations.

Tests

  • Extended Python test wiring to run a Numba-enabled suite when numba is available:
    • Updated test/python/CMakeLists.txt to add and activate a py:jited test group gated on numba.
    • Added test/python/jited.py registering a Numba-based adder.add transform over multiple NumPy dtypes and a verifier observer that asserts expected factors.
    • Added test/python/pyjited.jsonnet to generate layers via driver.cpp: 'generate_layers', using cppsource4py, and mapping the module to py: 'jited'.
    • Updated test/python/adder.py to assert an error when add transform registration is missing output_product_suffixes (expects TypeError mentioning “should have an output suffix”).

CI & security (CodeQL)

  • Resolved 21 CodeQL alerts since the prior branch point (mostly GitHub Actions workflow security issues around unsafe/untrusted checkout patterns and TOCTOU-style risks).
  • Affected workflows include clang-tidy-fix.yaml, clang-format-fix.yaml, python-fix.yaml, cmake-format-fix.yaml, jsonnet-format-fix.yaml, coverage.yaml, and several *-check.yaml jobs.

@greenc-FNAL

greenc-FNAL commented Jun 2, 2026

Copy link
Copy Markdown
Contributor

21 fixed, 0 new since branch point (7409297)
21 fixed, 0 new since previous report on PR (af07260)

✅ 21 CodeQL alerts resolved since the previous PR commit

  • Warning # 196 actions/untrusted-checkout-toctou/critical at .github/workflows/clang-tidy-fix.yaml:109:9 — Insufficient protection against execution of untrusted code on a privileged workflow (issue_comment).
  • Warning # 227 actions/untrusted-checkout-toctou/high at .github/workflows/clang-format-fix.yaml:94:9 — Insufficient protection against execution of untrusted code on a privileged workflow (issue_comment).
    Insufficient protection against execution of untrusted code on a privileged workflow (issue_comment).
  • Warning # 228 actions/untrusted-checkout-toctou/high at .github/workflows/python-fix.yaml:94:9 — Insufficient protection against execution of untrusted code on a privileged workflow (issue_comment).
    Insufficient protection against execution of untrusted code on a privileged workflow (issue_comment).
  • Warning # 229 actions/untrusted-checkout/high at .github/workflows/clang-format-fix.yaml:94:9 — Checkout of untrusted code in a privileged workflow with later potential execution (event trigger: issue_comment).
    Checkout of untrusted code in a privileged workflow with later potential execution (event trigger: issue_comment).
  • Warning # 230 actions/untrusted-checkout/high at .github/workflows/python-fix.yaml:94:9 — Checkout of untrusted code in a privileged workflow with later potential execution (event trigger: issue_comment).
    Checkout of untrusted code in a privileged workflow with later potential execution (event trigger: issue_comment).
  • Warning # 231 actions/untrusted-checkout-toctou/high at .github/workflows/cmake-format-fix.yaml:94:9 — Insufficient protection against execution of untrusted code on a privileged workflow (issue_comment).
    Insufficient protection against execution of untrusted code on a privileged workflow (issue_comment).
  • Warning # 232 actions/untrusted-checkout-toctou/high at .github/workflows/jsonnet-format-fix.yaml:95:9 — Insufficient protection against execution of untrusted code on a privileged workflow (issue_comment).
    Insufficient protection against execution of untrusted code on a privileged workflow (issue_comment).
  • Warning # 233 actions/untrusted-checkout/high at .github/workflows/cmake-format-fix.yaml:94:9 — Checkout of untrusted code in a privileged workflow with later potential execution (event trigger: issue_comment).
    Checkout of untrusted code in a privileged workflow with later potential execution (event trigger: issue_comment).
  • Warning # 234 actions/untrusted-checkout/high at .github/workflows/jsonnet-format-fix.yaml:95:9 — Checkout of untrusted code in a privileged workflow with later potential execution (event trigger: issue_comment).
    Checkout of untrusted code in a privileged workflow with later potential execution (event trigger: issue_comment).
  • Warning # 235 actions/untrusted-checkout/medium at .github/workflows/clang-format-check.yaml:82:9 — Potential unsafe checkout of untrusted pull request on privileged workflow.
  • Warning # 236 actions/untrusted-checkout/medium at .github/workflows/actionlint-check.yaml:86:9 — Potential unsafe checkout of untrusted pull request on privileged workflow.
  • Warning # 237 actions/untrusted-checkout/medium at .github/workflows/clang-tidy-check.yaml:59:9 — Potential unsafe checkout of untrusted pull request on privileged workflow.
  • Warning # 238 actions/untrusted-checkout/medium at .github/workflows/cmake-format-check.yaml:79:9 — Potential unsafe checkout of untrusted pull request on privileged workflow.
  • Warning # 239 actions/untrusted-checkout/medium at .github/workflows/cmake-build.yaml:159:9 — Potential unsafe checkout of untrusted pull request on privileged workflow.
  • Warning # 240 actions/untrusted-checkout/medium at .github/workflows/header-guards-check.yaml:82:9 — Potential unsafe checkout of untrusted pull request on privileged workflow.
  • Warning # 241 actions/untrusted-checkout/medium at .github/workflows/jsonnet-format-check.yaml:79:9 — Potential unsafe checkout of untrusted pull request on privileged workflow.
  • Warning # 242 actions/untrusted-checkout/medium at .github/workflows/markdown-check.yaml:82:9 — Potential unsafe checkout of untrusted pull request on privileged workflow.
  • Warning # 243 actions/untrusted-checkout/medium at .github/workflows/python-check.yaml:84:9 — Potential unsafe checkout of untrusted pull request on privileged workflow.
  • Warning # 244 actions/untrusted-checkout/medium at .github/workflows/yaml-check.yaml:76:9 — Potential unsafe checkout of untrusted pull request on privileged workflow.
  • Warning # 245 actions/untrusted-checkout-toctou/high at .github/workflows/coverage.yaml:386:9 — Insufficient protection against execution of untrusted code on a privileged workflow (issue_comment).
  • ✅ …and 1 more alerts (see Code Scanning for the full list).

✅ 21 CodeQL alerts resolved since the branch point

  • Warning # 196 actions/untrusted-checkout-toctou/critical at .github/workflows/clang-tidy-fix.yaml:109:9 — Insufficient protection against execution of untrusted code on a privileged workflow (issue_comment).
  • Warning # 227 actions/untrusted-checkout-toctou/high at .github/workflows/clang-format-fix.yaml:94:9 — Insufficient protection against execution of untrusted code on a privileged workflow (issue_comment).
    Insufficient protection against execution of untrusted code on a privileged workflow (issue_comment).
  • Warning # 228 actions/untrusted-checkout-toctou/high at .github/workflows/python-fix.yaml:94:9 — Insufficient protection against execution of untrusted code on a privileged workflow (issue_comment).
    Insufficient protection against execution of untrusted code on a privileged workflow (issue_comment).
  • Warning # 229 actions/untrusted-checkout/high at .github/workflows/clang-format-fix.yaml:94:9 — Checkout of untrusted code in a privileged workflow with later potential execution (event trigger: issue_comment).
    Checkout of untrusted code in a privileged workflow with later potential execution (event trigger: issue_comment).
  • Warning # 230 actions/untrusted-checkout/high at .github/workflows/python-fix.yaml:94:9 — Checkout of untrusted code in a privileged workflow with later potential execution (event trigger: issue_comment).
    Checkout of untrusted code in a privileged workflow with later potential execution (event trigger: issue_comment).
  • Warning # 231 actions/untrusted-checkout-toctou/high at .github/workflows/cmake-format-fix.yaml:94:9 — Insufficient protection against execution of untrusted code on a privileged workflow (issue_comment).
    Insufficient protection against execution of untrusted code on a privileged workflow (issue_comment).
  • Warning # 232 actions/untrusted-checkout-toctou/high at .github/workflows/jsonnet-format-fix.yaml:95:9 — Insufficient protection against execution of untrusted code on a privileged workflow (issue_comment).
    Insufficient protection against execution of untrusted code on a privileged workflow (issue_comment).
  • Warning # 233 actions/untrusted-checkout/high at .github/workflows/cmake-format-fix.yaml:94:9 — Checkout of untrusted code in a privileged workflow with later potential execution (event trigger: issue_comment).
    Checkout of untrusted code in a privileged workflow with later potential execution (event trigger: issue_comment).
  • Warning # 234 actions/untrusted-checkout/high at .github/workflows/jsonnet-format-fix.yaml:95:9 — Checkout of untrusted code in a privileged workflow with later potential execution (event trigger: issue_comment).
    Checkout of untrusted code in a privileged workflow with later potential execution (event trigger: issue_comment).
  • Warning # 235 actions/untrusted-checkout/medium at .github/workflows/clang-format-check.yaml:82:9 — Potential unsafe checkout of untrusted pull request on privileged workflow.
  • Warning # 236 actions/untrusted-checkout/medium at .github/workflows/actionlint-check.yaml:86:9 — Potential unsafe checkout of untrusted pull request on privileged workflow.
  • Warning # 237 actions/untrusted-checkout/medium at .github/workflows/clang-tidy-check.yaml:59:9 — Potential unsafe checkout of untrusted pull request on privileged workflow.
  • Warning # 238 actions/untrusted-checkout/medium at .github/workflows/cmake-format-check.yaml:79:9 — Potential unsafe checkout of untrusted pull request on privileged workflow.
  • Warning # 239 actions/untrusted-checkout/medium at .github/workflows/cmake-build.yaml:159:9 — Potential unsafe checkout of untrusted pull request on privileged workflow.
  • Warning # 240 actions/untrusted-checkout/medium at .github/workflows/header-guards-check.yaml:82:9 — Potential unsafe checkout of untrusted pull request on privileged workflow.
  • Warning # 241 actions/untrusted-checkout/medium at .github/workflows/jsonnet-format-check.yaml:79:9 — Potential unsafe checkout of untrusted pull request on privileged workflow.
  • Warning # 242 actions/untrusted-checkout/medium at .github/workflows/markdown-check.yaml:82:9 — Potential unsafe checkout of untrusted pull request on privileged workflow.
  • Warning # 243 actions/untrusted-checkout/medium at .github/workflows/python-check.yaml:84:9 — Potential unsafe checkout of untrusted pull request on privileged workflow.
  • Warning # 244 actions/untrusted-checkout/medium at .github/workflows/yaml-check.yaml:76:9 — Potential unsafe checkout of untrusted pull request on privileged workflow.
  • Warning # 245 actions/untrusted-checkout-toctou/high at .github/workflows/coverage.yaml:386:9 — Insufficient protection against execution of untrusted code on a privileged workflow (issue_comment).
  • ✅ …and 1 more alerts (see Code Scanning for the full list).

Review the full CodeQL report for details.

@github-actions

github-actions Bot commented Jun 2, 2026

Copy link
Copy Markdown
Contributor

Clang-Tidy Check Results

55 new issue(s) introduced by this patch (5842 total).

New issues on modified lines:

  • /__w/phlex/phlex/phlex-src/plugins/python/src/dyncall.cpp:17: warning: variable 'ffi_t' is non-const and globally accessible, consider making it const
  • /__w/phlex/phlex/phlex-src/plugins/python/src/dyncall.cpp:62: warning: do not use array subscript when the index is not an integer constant expression
  • /__w/phlex/phlex/phlex-src/plugins/python/src/dyncall.cpp:67: warning: variable 'status' is not initialized
  • /__w/phlex/phlex/phlex-src/plugins/python/src/dyncall.cpp:69: warning: do not use array subscript when the index is not an integer constant expression
  • /__w/phlex/phlex/phlex-src/plugins/python/src/dyncall.cpp:71: warning: do not use array subscript when the index is not an integer constant expression
  • /__w/phlex/phlex/phlex-src/plugins/python/src/dyncall.cpp:76: warning: do not use C-style cast to convert between unrelated types
  • /__w/phlex/phlex/phlex-src/plugins/python/src/dyncall.hpp:72: warning: do not access members of unions; consider using (boost::)variant instead
  • /__w/phlex/phlex/phlex-src/plugins/python/src/dyncall.hpp:73: warning: do not access members of unions; consider using (boost::)variant instead
  • /__w/phlex/phlex/phlex-src/plugins/python/src/dyncall.hpp:74: warning: do not access members of unions; consider using (boost::)variant instead
  • /__w/phlex/phlex/phlex-src/plugins/python/src/dyncall.hpp:75: warning: do not access members of unions; consider using (boost::)variant instead
  • /__w/phlex/phlex/phlex-src/plugins/python/src/dyncall.hpp:76: warning: do not access members of unions; consider using (boost::)variant instead
  • /__w/phlex/phlex/phlex-src/plugins/python/src/dyncall.hpp:77: warning: do not access members of unions; consider using (boost::)variant instead
  • /__w/phlex/phlex/phlex-src/plugins/python/src/dyncall.hpp:78: warning: do not access members of unions; consider using (boost::)variant instead
  • /__w/phlex/phlex/phlex-src/plugins/python/src/dyncall.hpp:79: warning: do not access members of unions; consider using (boost::)variant instead
  • /__w/phlex/phlex/phlex-src/plugins/python/src/dyncall.hpp:80: warning: do not access members of unions; consider using (boost::)variant instead
  • /__w/phlex/phlex/phlex-src/plugins/python/src/dyncall.hpp:81: warning: do not access members of unions; consider using (boost::)variant instead
  • /__w/phlex/phlex/phlex-src/plugins/python/src/dyncall.hpp:82: warning: do not access members of unions; consider using (boost::)variant instead
  • /__w/phlex/phlex/phlex-src/plugins/python/src/dyncall.hpp:83: warning: do not access members of unions; consider using (boost::)variant instead
  • /__w/phlex/phlex/phlex-src/plugins/python/src/dyncall.hpp:84: warning: do not access members of unions; consider using (boost::)variant instead
  • /__w/phlex/phlex/phlex-src/plugins/python/src/dyncall.hpp:89: warning: do not access members of unions; consider using (boost::)variant instead
  • /__w/phlex/phlex/phlex-src/plugins/python/src/dyncall.hpp:90: warning: do not access members of unions; consider using (boost::)variant instead
  • /__w/phlex/phlex/phlex-src/plugins/python/src/dyncall.hpp:91: warning: do not access members of unions; consider using (boost::)variant instead
  • /__w/phlex/phlex/phlex-src/plugins/python/src/dyncall.hpp:92: warning: do not access members of unions; consider using (boost::)variant instead
  • /__w/phlex/phlex/phlex-src/plugins/python/src/dyncall.hpp:93: warning: do not access members of unions; consider using (boost::)variant instead
  • /__w/phlex/phlex/phlex-src/plugins/python/src/dyncall.hpp:94: warning: do not access members of unions; consider using (boost::)variant instead
  • /__w/phlex/phlex/phlex-src/plugins/python/src/dyncall.hpp:95: warning: do not access members of unions; consider using (boost::)variant instead
  • /__w/phlex/phlex/phlex-src/plugins/python/src/dyncall.hpp:96: warning: do not access members of unions; consider using (boost::)variant instead
  • /__w/phlex/phlex/phlex-src/plugins/python/src/dyncall.hpp:96: warning: integer literal has suffix 'l', which is not uppercase
  • /__w/phlex/phlex/phlex-src/plugins/python/src/dyncall.hpp:97: warning: do not access members of unions; consider using (boost::)variant instead
  • /__w/phlex/phlex/phlex-src/plugins/python/src/dyncall.hpp:98: warning: do not access members of unions; consider using (boost::)variant instead
  • /__w/phlex/phlex/phlex-src/plugins/python/src/dyncall.hpp:99: warning: do not access members of unions; consider using (boost::)variant instead
  • /__w/phlex/phlex/phlex-src/plugins/python/src/dyncall.hpp:100: warning: do not access members of unions; consider using (boost::)variant instead
  • /__w/phlex/phlex/phlex-src/plugins/python/src/dyncall.hpp:108: warning: multilevel pointer conversion from 'void **' to 'void *', please use explicit cast
  • /__w/phlex/phlex/phlex-src/plugins/python/src/dyncall.hpp:108: warning: do not access members of unions; consider using (boost::)variant instead
  • /__w/phlex/phlex/phlex-src/plugins/python/src/dyncall.hpp:110: warning: do not access members of unions; consider using (boost::)variant instead
  • /__w/phlex/phlex/phlex-src/plugins/python/src/dyncall.hpp:112: warning: do not access members of unions; consider using (boost::)variant instead
  • /__w/phlex/phlex/phlex-src/plugins/python/src/dyncall.hpp:114: warning: do not access members of unions; consider using (boost::)variant instead
  • /__w/phlex/phlex/phlex-src/plugins/python/src/dyncall.hpp:116: warning: do not access members of unions; consider using (boost::)variant instead
  • /__w/phlex/phlex/phlex-src/plugins/python/src/dyncall.hpp:118: warning: do not access members of unions; consider using (boost::)variant instead
  • /__w/phlex/phlex/phlex-src/plugins/python/src/dyncall.hpp:120: warning: do not access members of unions; consider using (boost::)variant instead
  • /__w/phlex/phlex/phlex-src/plugins/python/src/dyncall.hpp:122: warning: do not access members of unions; consider using (boost::)variant instead
  • /__w/phlex/phlex/phlex-src/plugins/python/src/dyncall.hpp:124: warning: do not access members of unions; consider using (boost::)variant instead
  • /__w/phlex/phlex/phlex-src/plugins/python/src/dyncall.hpp:126: warning: do not access members of unions; consider using (boost::)variant instead
  • /__w/phlex/phlex/phlex-src/plugins/python/src/dyncall.hpp:128: warning: do not access members of unions; consider using (boost::)variant instead
  • /__w/phlex/phlex/phlex-src/plugins/python/src/dyncall.hpp:130: warning: do not access members of unions; consider using (boost::)variant instead
  • /__w/phlex/phlex/phlex-src/plugins/python/src/modulewrap.cpp:110: warning: do not access members of unions; consider using (boost::)variant instead
  • /__w/phlex/phlex/phlex-src/plugins/python/src/modulewrap.cpp:169: warning: do not use C-style cast to convert between unrelated types
  • /__w/phlex/phlex/phlex-src/plugins/python/src/modulewrap.cpp:187: warning: do not access members of unions; consider using (boost::)variant instead
  • /__w/phlex/phlex/phlex-src/plugins/python/src/modulewrap.cpp:200: warning: do not use C-style cast to convert between unrelated types
  • /__w/phlex/phlex/phlex-src/plugins/python/src/modulewrap.cpp:200: warning: do not access members of unions; consider using (boost::)variant instead
  • /__w/phlex/phlex/phlex-src/plugins/python/src/modulewrap.cpp:208: warning: do not access members of unions; consider using (boost::)variant instead
  • /__w/phlex/phlex/phlex-src/plugins/python/src/modulewrap.cpp:222: warning: 'm_rtype' should be initialized in a member initializer of the constructor
  • /__w/phlex/phlex/phlex-src/plugins/python/src/modulewrap.cpp:602: warning: do not access members of unions; consider using (boost::)variant instead
  • /__w/phlex/phlex/phlex-src/plugins/python/src/modulewrap.cpp:603: warning: do not access members of unions; consider using (boost::)variant instead
  • /__w/phlex/phlex/phlex-src/plugins/python/src/modulewrap.cpp:976: warning: 'func' used after it was forwarded

All issues by check:

  • readability-identifier-naming: 1826
  • readability-redundant-typename: 1217
  • readability-redundant-member-init: 1138
  • performance-unnecessary-value-param: 478
  • readability-avoid-const-params-in-decls: 239
  • modernize-pass-by-value: 199
  • readability-braces-around-statements: 129
  • cppcoreguidelines-pro-type-union-access: 91
  • readability-convert-member-functions-to-static: 79
  • modernize-use-designated-initializers: 72
  • readability-const-return-type: 47
  • modernize-avoid-c-style-cast: 33
  • modernize-use-auto: 28
  • readability-inconsistent-ifelse-braces: 21
  • readability-qualified-auto: 20
  • modernize-use-using: 19
  • readability-redundant-control-flow: 19
  • modernize-avoid-c-arrays: 18
  • readability-math-missing-parentheses: 17
  • modernize-use-equals-default: 14
  • readability-function-size: 13
  • readability-static-definition-in-anonymous-namespace: 13
  • modernize-return-braced-init-list: 10
  • modernize-concat-nested-namespaces: 10
  • cppcoreguidelines-pro-type-cstyle-cast: 9
  • readability-isolate-declaration: 8
  • readability-inconsistent-declaration-parameter-name: 7
  • cppcoreguidelines-special-member-functions: 7
  • readability-container-contains: 7
  • modernize-use-starts-ends-with: 6
  • readability-redundant-casting: 5
  • readability-redundant-access-specifiers: 5
  • modernize-use-ranges: 5
  • readability-container-size-empty: 5
  • bugprone-branch-clone: 3
  • cppcoreguidelines-pro-bounds-constant-array-index: 3
  • modernize-use-std-numbers: 3
  • readability-else-after-return: 2
  • cert-dcl16-c: 2
  • bugprone-multi-level-implicit-pointer-conversion: 2
  • clang-analyzer-security.ArrayBound: 2
  • modernize-make-shared: 1
  • cppcoreguidelines-avoid-non-const-global-variables: 1
  • cppcoreguidelines-init-variables: 1
  • modernize-use-emplace: 1
  • cppcoreguidelines-prefer-member-initializer: 1
  • readability-simplify-boolean-expr: 1
  • modernize-use-integer-sign-comparison: 1
  • readability-use-anyofallof: 1
  • bugprone-use-after-move: 1
  • modernize-redundant-void-arg: 1
  • readability-redundant-string-init: 1

See inline comments for details. Comment @phlexbot tidy-fix to auto-fix.

@codecov

codecov Bot commented Jun 2, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 75.36657% with 84 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
plugins/python/src/modulewrap.cpp 74.41% 35 Missing and 31 partials ⚠️
plugins/python/src/dyncall.cpp 81.96% 8 Missing and 3 partials ⚠️
plugins/python/src/dyncall.hpp 66.66% 5 Missing ⚠️
plugins/python/python/phlex/_typing.py 71.42% 2 Missing ⚠️
@@            Coverage Diff             @@
##             main     #626      +/-   ##
==========================================
- Coverage   83.55%   82.95%   -0.61%     
==========================================
  Files         170      172       +2     
  Lines        6283     6436     +153     
  Branches      706      742      +36     
==========================================
+ Hits         5250     5339      +89     
- Misses        810      855      +45     
- Partials      223      242      +19     
Flag Coverage Δ
scripts 78.86% <ø> (ø)
unittests 84.95% <75.36%> (-0.99%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
plugins/python/python/phlex/_typing.py 92.30% <71.42%> (-2.06%) ⬇️
plugins/python/src/dyncall.hpp 66.66% <66.66%> (ø)
plugins/python/src/dyncall.cpp 81.96% <81.96%> (ø)
plugins/python/src/modulewrap.cpp 74.70% <74.41%> (-4.61%) ⬇️

... and 2 files with indirect coverage changes


Continue to review full report in Codecov by Harness.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 7409297...a0fb468. Read the comment docs.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@github-actions

github-actions Bot commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

Clang-Tidy Check Results

3 new issue(s) introduced by this patch (5777 total).

New issues on modified lines:

  • /__w/phlex/phlex/phlex-src/plugins/python/src/dyncall.hpp:35: warning: declaration uses identifier '_object', which is reserved in the global namespace
  • /__w/phlex/phlex/phlex-src/plugins/python/src/modulewrap.cpp:969: warning: forwarding reference parameter 'func' is never forwarded inside the function body
  • /__w/phlex/phlex/phlex-src/plugins/python/src/dyncall.cpp:66: warning: repeated branch body in conditional chain

All issues by check:

  • readability-identifier-naming: 1807
  • readability-redundant-typename: 1217
  • readability-redundant-member-init: 1138
  • performance-unnecessary-value-param: 479
  • readability-avoid-const-params-in-decls: 257
  • modernize-pass-by-value: 200
  • readability-braces-around-statements: 116
  • readability-convert-member-functions-to-static: 80
  • modernize-use-designated-initializers: 72
  • readability-use-concise-preprocessor-directives: 60
  • readability-const-return-type: 47
  • modernize-avoid-c-style-cast: 27
  • modernize-use-auto: 26
  • modernize-use-using: 21
  • readability-inconsistent-ifelse-braces: 21
  • readability-qualified-auto: 20
  • readability-redundant-control-flow: 19
  • readability-math-missing-parentheses: 17
  • modernize-avoid-c-arrays: 16
  • modernize-use-equals-default: 14
  • readability-static-definition-in-anonymous-namespace: 14
  • readability-function-size: 12
  • modernize-concat-nested-namespaces: 10
  • modernize-return-braced-init-list: 10
  • readability-isolate-declaration: 8
  • readability-inconsistent-declaration-parameter-name: 7
  • readability-container-contains: 7
  • cppcoreguidelines-special-member-functions: 7
  • modernize-use-starts-ends-with: 6
  • modernize-use-ranges: 5
  • readability-redundant-casting: 5
  • readability-container-size-empty: 5
  • readability-redundant-access-specifiers: 5
  • bugprone-branch-clone: 4
  • modernize-use-std-numbers: 3
  • readability-else-after-return: 2
  • clang-analyzer-security.ArrayBound: 2
  • bugprone-reserved-identifier: 2
  • modernize-redundant-void-arg: 1
  • modernize-make-shared: 1
  • readability-redundant-string-init: 1
  • modernize-use-emplace: 1
  • readability-simplify-boolean-expr: 1
  • modernize-use-integer-sign-comparison: 1
  • readability-use-anyofallof: 1
  • cppcoreguidelines-missing-std-forward: 1
  • performance-move-const-arg: 1

See inline comments for details. Comment @phlexbot tidy-fix to auto-fix.

@github-actions

github-actions Bot commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

Clang-Tidy Check Results

2 new issue(s) introduced by this patch (5769 total).

New issues on modified lines:

  • /__w/phlex/phlex/phlex-src/plugins/python/src/dyncall.cpp:67: warning: repeated branch body in conditional chain
  • /__w/phlex/phlex/phlex-src/plugins/python/src/modulewrap.cpp:978: warning: 'func' used after it was forwarded

All issues by check:

  • readability-identifier-naming: 1804
  • readability-redundant-typename: 1217
  • readability-redundant-member-init: 1138
  • performance-unnecessary-value-param: 479
  • readability-avoid-const-params-in-decls: 257
  • modernize-pass-by-value: 200
  • readability-braces-around-statements: 116
  • readability-convert-member-functions-to-static: 80
  • modernize-use-designated-initializers: 72
  • readability-use-concise-preprocessor-directives: 60
  • readability-const-return-type: 47
  • modernize-avoid-c-style-cast: 27
  • modernize-use-auto: 26
  • readability-inconsistent-ifelse-braces: 21
  • readability-qualified-auto: 20
  • modernize-use-using: 19
  • readability-redundant-control-flow: 19
  • readability-math-missing-parentheses: 17
  • modernize-avoid-c-arrays: 15
  • readability-static-definition-in-anonymous-namespace: 14
  • modernize-use-equals-default: 14
  • readability-function-size: 12
  • modernize-return-braced-init-list: 10
  • modernize-concat-nested-namespaces: 10
  • readability-isolate-declaration: 8
  • readability-inconsistent-declaration-parameter-name: 7
  • cppcoreguidelines-special-member-functions: 7
  • readability-container-contains: 7
  • modernize-use-starts-ends-with: 6
  • readability-redundant-casting: 5
  • readability-redundant-access-specifiers: 5
  • modernize-use-ranges: 5
  • readability-container-size-empty: 5
  • bugprone-branch-clone: 4
  • modernize-use-std-numbers: 3
  • readability-else-after-return: 2
  • clang-analyzer-security.ArrayBound: 2
  • readability-redundant-string-init: 1
  • performance-move-const-arg: 1
  • modernize-make-shared: 1
  • modernize-use-emplace: 1
  • readability-simplify-boolean-expr: 1
  • modernize-use-integer-sign-comparison: 1
  • readability-use-anyofallof: 1
  • bugprone-use-after-move: 1
  • modernize-redundant-void-arg: 1

See inline comments for details. Comment @phlexbot tidy-fix to auto-fix.

@wlav

wlav commented Jun 3, 2026

Copy link
Copy Markdown
Contributor Author

@phlexbot header-guards-fix

@github-actions

github-actions Bot commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

Automatic header-guards fixes pushed (commit ea7dff7).
⚠️ Note: Some issues may require manual review and fixing.

@github-actions

github-actions Bot commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

Clang-Tidy Check Results

2 new issue(s) introduced by this patch (5767 total).

New issues on modified lines:

  • /__w/phlex/phlex/phlex-src/plugins/python/src/dyncall.cpp:67: warning: repeated branch body in conditional chain
  • /__w/phlex/phlex/phlex-src/plugins/python/src/modulewrap.cpp:978: warning: 'func' used after it was forwarded

All issues by check:

  • readability-identifier-naming: 1802
  • readability-redundant-typename: 1217
  • readability-redundant-member-init: 1138
  • performance-unnecessary-value-param: 479
  • readability-avoid-const-params-in-decls: 257
  • modernize-pass-by-value: 200
  • readability-braces-around-statements: 116
  • readability-convert-member-functions-to-static: 80
  • modernize-use-designated-initializers: 72
  • readability-use-concise-preprocessor-directives: 60
  • readability-const-return-type: 47
  • modernize-avoid-c-style-cast: 27
  • modernize-use-auto: 26
  • readability-inconsistent-ifelse-braces: 21
  • readability-qualified-auto: 20
  • modernize-use-using: 19
  • readability-redundant-control-flow: 19
  • readability-math-missing-parentheses: 17
  • modernize-avoid-c-arrays: 15
  • modernize-use-equals-default: 14
  • readability-static-definition-in-anonymous-namespace: 14
  • readability-function-size: 12
  • modernize-concat-nested-namespaces: 10
  • modernize-return-braced-init-list: 10
  • readability-isolate-declaration: 8
  • readability-container-contains: 7
  • readability-inconsistent-declaration-parameter-name: 7
  • cppcoreguidelines-special-member-functions: 7
  • modernize-use-starts-ends-with: 6
  • readability-redundant-access-specifiers: 5
  • modernize-use-ranges: 5
  • readability-container-size-empty: 5
  • readability-redundant-casting: 5
  • bugprone-branch-clone: 4
  • modernize-use-std-numbers: 3
  • clang-analyzer-security.ArrayBound: 2
  • readability-else-after-return: 2
  • modernize-redundant-void-arg: 1
  • modernize-use-emplace: 1
  • readability-simplify-boolean-expr: 1
  • modernize-use-integer-sign-comparison: 1
  • readability-use-anyofallof: 1
  • bugprone-use-after-move: 1
  • modernize-make-shared: 1
  • performance-move-const-arg: 1
  • readability-redundant-string-init: 1

See inline comments for details. Comment @phlexbot tidy-fix to auto-fix.

Comment thread plugins/python/src/modulewrap.cpp
@knoepfel knoepfel added this to the Prototype 0.3 milestone Jun 24, 2026
@greenc-FNAL

Copy link
Copy Markdown
Contributor

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Jun 26, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Full review finished.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 11

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
plugins/python/src/modulewrap.cpp (1)

298-327: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Release the PySequence_Fast result in validate_input.

PySequence_Fast returns a new reference, but this function never decrefs coll; validate_output handles the same pattern correctly. Transform/observe registration now leaks one sequence object per call.

Suggested fix
     if (PyErr_Occurred())
       cargs.clear(); // error handled through Python
 
+    Py_DECREF(coll);
     return cargs;
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@plugins/python/src/modulewrap.cpp` around lines 298 - 327, The validate_input
helper leaks the PySequence_Fast result because coll is never released after
use. Update validate_input to decref the PySequence_Fast-owned coll before every
return path, including the early failure cases and the normal exit, using the
same ownership pattern already used in validate_output.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@plugins/python/src/dyncall.cpp`:
- Around line 106-109: The new local in the argument-count setup inside
dyncall.cpp should follow the repo’s lower_case C++ naming rule. Rename the size
variable used with the unique_ptr allocations in this block from the uppercase
form to a lower_case name, and keep the rest of the logic in the same dyncall
conversion path unchanged.

In `@plugins/python/src/dyncall.hpp`:
- Around line 38-53: The new public alias inside dcarg uses a PascalCase name
that violates the repository’s C++ naming convention. Rename FFIType to a
lower_case identifier, and update its usage for m_value accordingly so dcarg
stays consistent with the rest of the dyncall API.
- Around line 21-24: The header is not self-contained and violates the C++
identifier naming rule: add the missing <string> include so dcarg::from_str can
use std::string without relying on transitive includes, and rename the FFIType
alias to a lower_case name such as ffi_type throughout the dyncall.hpp
declarations and any related uses while keeping the rest of the dcarg API
unchanged.

In `@plugins/python/src/modulewrap.cpp`:
- Line 50: The constexpr constant MAX_SUPPORTED_ARGS in modulewrap.cpp should be
renamed to lower_case to match the C++ identifier convention. Update the
declaration itself to max_supported_args and make sure the two call sites that
compare against or use this limit in the module wrapping logic are also switched
to the new name, keeping the behavior unchanged.
- Around line 1059-1061: The transform registration in modulewrap.cpp indexes
output_suffixes[0] without first confirming there is at least one suffix. Update
the transform setup around the pyname/pyoutput/out_type assignments to validate
output_product_suffixes (and the derived output_suffixes) is non-empty before
any indexing, and reject the registration with a clear error if it is omitted or
empty.
- Around line 599-609: The provider callback conversion in
provider_cb_##name::operator() does not propagate Python conversion failures, so
a bad provider return can leave a pending Python error while still returning a
C++ value. Update the operator() path that calls frompy(pyres) to check
msg_from_py_error (as py_to_* does) and convert any Python error into a failure
before returning; use the existing provider_cb_* and frompy helpers to locate
the fix.
- Around line 740-741: The transform call in modulewrap.cpp is hardcoding the
converter concurrency instead of using the parsed/default setting. Update the
ph_module->transform invocation to remove the explicit casted value and keep the
converter path serial unless a valid concurrency enum/API value is intentionally
supplied. Use the transform call site and the concurrency argument handling
around name and converter to locate and fix it.
- Around line 128-156: The copy/assignment logic in py_callback_base is still
using Py_INCREF/Py_DECREF directly, which can crash when m_callable has been
cleared by move construction or move assignment. Update the copy constructor,
copy assignment operator, and move assignment operator in py_callback_base to
use null-safe reference-count handling with Py_XINCREF/Py_XDECREF (or equivalent
guarded checks) so assigning from or into a moved-from instance is safe. Keep
the existing GIL protection around all reference-count changes.

In `@test/python/CMakeLists.txt`:
- Around line 291-301: The `py:phlex` test is being configured before
`PYTHON_TEST_FILES` includes `test_phlex.py`, so the test may not be generated
or may fail when `set_property(TEST py:phlex ...)` runs. Move the
`set(PYTHON_TEST_FILES ${PYTHON_TEST_FILES} test_phlex.py)` update in the
`HAS_CPPYY` block to before the test-generation step, keeping the `py:phlex`
setup and `PYTHON_TEST_FILES` mutation aligned.

In `@test/python/jited.py`:
- Line 8: Replace the internal numba.core.decorators import in jited.py with
Numba’s public cfunc API so the test no longer depends on unstable internals.
Update the import and any references that use nb_dec so they call cfunc
directly, keeping the test aligned with the supported public symbol and
resilient across Numba versions.

In `@test/python/pyjited.jsonnet`:
- Around line 13-16: The pyjited module stanza is missing the input wiring
needed for the transforms registered in jited.py, so the Numba path never gets
exercised. Update the modules entry for pyadd in pyjited.jsonnet to include the
same kind of input list used by pyadd.jsonnet, ensuring cppsource4py products
are connected for the suffixes consumed by jited.py (such as i, j, u1, and u2).
Keep the fix centered on the pyadd module definition and the jited.py transform
expectations.

---

Outside diff comments:
In `@plugins/python/src/modulewrap.cpp`:
- Around line 298-327: The validate_input helper leaks the PySequence_Fast
result because coll is never released after use. Update validate_input to decref
the PySequence_Fast-owned coll before every return path, including the early
failure cases and the normal exit, using the same ownership pattern already used
in validate_output.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: d890ab78-b06b-42ff-ab15-69f594e3c6f5

📥 Commits

Reviewing files that changed from the base of the PR and between cb81c8b and 025390c.

📒 Files selected for processing (8)
  • plugins/python/CMakeLists.txt
  • plugins/python/python/phlex/_typing.py
  • plugins/python/src/dyncall.cpp
  • plugins/python/src/dyncall.hpp
  • plugins/python/src/modulewrap.cpp
  • test/python/CMakeLists.txt
  • test/python/jited.py
  • test/python/pyjited.jsonnet
📜 Review details
⚠️ CI failures not shown inline (9)

GitHub Actions: wlav checking C++ code format / 0_clang-format-check.txt: wlav checking C++ code format

Conclusion: failure

View job details

##[group]Run REPO_NAME="${REPO##*/}"
 �[36;1mREPO_NAME="${REPO##*/}"�[0m
 �[36;1mif [ "success" = 'success' ]; then�[0m
 �[36;1m  echo "✅ clang-format check passed."�[0m
 �[36;1melse�[0m
 �[36;1m  echo "::error::clang-format check failed. Please review the output above for details."�[0m

GitHub Actions: wlav checking C++ code with clang-tidy / 1_clang-tidy-check.txt: wlav checking C++ code with clang-tidy

Conclusion: failure

View job details

##[group]Run . /entrypoint.sh
 �[36;1m. /entrypoint.sh�[0m
 �[36;1mREPO_NAME="${REPO##*/}"�[0m
 �[36;1mSOURCE_DIR="$GITHUB_WORKSPACE/$SOURCE_PATH"�[0m
 �[36;1mBUILD_DIR="$GITHUB_WORKSPACE/$BUILD_PATH"�[0m
 �[36;1m�[0m
 �[36;1m# run-clang-tidy runs clang-tidy on every translation unit in�[0m
 �[36;1m# compile_commands.json in parallel and merges the per-TU fix YAML files�[0m
 �[36;1m# into a single comprehensive clang-tidy-fixes.yaml.  The alternative�[0m
 �[36;1m# (setting CMAKE_CXX_CLANG_TIDY=clang-tidy;--export-fixes=... and�[0m
 �[36;1m# building with -j) suffers from a race condition: every parallel�[0m
 �[36;1m# clang-tidy invocation independently overwrites the same output file, so�[0m
 �[36;1m# only the fixes from whichever translation unit finishes last are�[0m
 �[36;1m# retained.�[0m
 �[36;1m#�[0m
 �[36;1m# Path arguments are substring-matched against file paths in�[0m
 �[36;1m# compile_commands.json; restricting to the source directory automatically�[0m
 �[36;1m# excludes generated files (e.g. version.cpp, ROOT dictionaries) that live�[0m
 �[36;1m# in the build directory and lack access to the .clang-tidy config.�[0m
 �[36;1m#�[0m
 �[36;1m# run-clang-tidy validates the check list by calling clang-tidy from its�[0m
 �[36;1m# working directory; run from the source root so that clang-tidy discovers�[0m
 �[36;1m# the .clang-tidy config file there, preventing a spurious "No checks�[0m
 �[36;1m# enabled." error.�[0m
 �[36;1mif ! command -v run-clang-tidy >/dev/null 2>&1; then�[0m
 �[36;1m  echo "::error::run-clang-tidy not found in PATH; cannot run clang-tidy checks"�[0m

GitHub Actions: wlav checking Python code / 0_python-check.txt: wlav checking Python code

Conclusion: failure

View job details

##[group]Run REPO_NAME="${REPO##*/}"
 �[36;1mREPO_NAME="${REPO##*/}"�[0m
 �[36;1mif [ "success" = 'success' ] && [ "success" = 'success' ]; then�[0m
 �[36;1m  echo "✅ Python checks passed."�[0m
 �[36;1melse�[0m
 �[36;1m  echo "::error::Python checks failed. Comment '@${REPO_NAME}bot python-fix' on the PR to attempt auto-fix."�[0m

GitHub Actions: wlav checking Python code / 1_scripts-test.txt: wlav checking Python code

Conclusion: failure

View job details

test_nothing_written_when_no_alerts PASSED [ 23%]
 scripts/test/test_check_codeql_alerts.py::TestMainSarifMode::test_new_alert_returns_zero_and_writes_comment PASSED [ 23%]
 scripts/test/test_check_codeql_alerts.py::TestMainSarifMode::test_absent_alert_returns_zero_and_writes_comment PASSED [ 24%]
 scripts/test/test_check_codeql_alerts.py::TestMainSarifMode::test_no_alerts_returns_zero_no_comment PASSED [ 24%]
 scripts/test/test_check_codeql_alerts.py::TestMainSarifMode::test_below_threshold_alert_not_reported PASSED [ 24%]
 scripts/test/test_check_codeql_alerts.py::TestMainSarifMode::test_missing_sarif_exits_nonzero PASSED [ 24%]
 scripts/test/test_check_codeql_alerts.py::TestMainSarifMode::test_github_output_written PASSED [ 24%]
 scripts/test/test_check_codeql_alerts.py::TestMainSarifMode::test_github_output_false_when_no_alerts PASSED [ 25%]
 scripts/test/test_check_codeql_alerts.py::TestMainSarifMode::test_directory_of_sarif_files PASSED [ 25%]
 scripts/test/test_check_codeql_alerts.py::TestMainSarifMode::test_sarif_mode_pr_ref_produces_filtered_url PASSED [ 25%]
 scripts/test/test_check_codeql_alerts.py::TestMainSarifMode::test_non_integer_pr_ref_no_filtered_url PASSED [ 25%]
 scripts/test/test_check_codeql_alerts.py::TestMainApiMode::test_api_mode_new_alert PASSED [ 25%]
 scripts/test/test_check_codeql_alerts.py::TestMainApiMode::test_api_mode_min_level_filtering PASSED [ 26%]
 scripts/test/test_check_codeql_alerts.py::TestMainApiMode::test_api_mode_github_api_error_exits_2 PASSED [ 26%]
 scripts/test/test_check_codeql_alerts.py::TestMainApiMode::test_api_mode_missing_github_repository_exits_2 PASSED [ 26%]
 scripts/test/test_check_codeql_alerts.py::TestMainApiMode::test_api_mode_skipped_when_sarif_has_baseline PASSED [ 26%]
 scripts/test/test_check_codeql_alerts.py::TestMainApiModeWithPrRef::test_api_mode_pr_ref_produces_filtered_url PASSED [ 27%]
 scripts/test/test_check_codeql_alerts.py::TestMainEntrypoint::test_entrypoint_no_alerts_exits_zero PASSED [ ...

GitHub Actions: wlav checking Jsonnet format / 0_jsonnet-format-check.txt: wlav checking Jsonnet format

Conclusion: failure

View job details

##[group]Run REPO_NAME="${REPO##*/}"
 �[36;1mREPO_NAME="${REPO##*/}"�[0m
 �[36;1mif [ "success" = 'success' ]; then�[0m
 �[36;1m  echo "✅ Jsonnet formatting check passed."�[0m
 �[36;1melse�[0m
 �[36;1m  echo "::error::Jsonnet formatting issues found. Please review the output above for details."�[0m

GitHub Actions: wlav building and testing Framework-R-D/phlex / 1_build (gcc, none).txt: wlav building and testing Framework-R-D/phlex

Conclusion: failure

View job details

�[36;1mecho "::group::Running ctest"�[0m
 �[36;1mif ctest --progress --output-on-failure -j "$(nproc)"; then�[0m
 �[36;1m  echo "::endgroup::"�[0m
 �[36;1m  echo "✅ All tests passed."�[0m
 �[36;1melse�[0m
 �[36;1m  echo "::endgroup::"�[0m
 �[36;1m  echo "::error:: Some tests failed."�[0m

GitHub Actions: wlav running code coverage / 2_coverage.txt: wlav running code coverage

Conclusion: failure

View job details

�[36;1mecho "::group::Running ctest for coverage"�[0m
 �[36;1mif ctest --progress --output-on-failure -j "$(nproc)"; then�[0m
 �[36;1m  echo "::endgroup::"�[0m
 �[36;1m  echo "✅ All tests passed."�[0m
 �[36;1melse�[0m
 �[36;1m  echo "::endgroup::"�[0m
 �[36;1m  echo "::error::Some tests failed."�[0m

GitHub Actions: wlav checking CMake format / 0_cmake-format-check.txt: wlav checking CMake format

Conclusion: failure

View job details

##[group]Run REPO_NAME="${REPO##*/}"
 �[36;1mREPO_NAME="${REPO##*/}"�[0m
 �[36;1mif [ "success" = 'success' ]; then�[0m
 �[36;1m  echo "✅ All CMake files are properly formatted."�[0m
 �[36;1melse�[0m
 �[36;1m  echo "::error::Found files with formatting issues."�[0m

GitHub Actions: CodeQL Analysis / 3_determine-languages.txt: Initial Numba support

Conclusion: failure

View job details

##[group]Run # If detection was skipped, use all languages or the provided language-matrix
 �[36;1m# If detection was skipped, use all languages or the provided language-matrix�[0m
 �[36;1mif [ "${SKIP_DETECTION}" = "true" ]; then�[0m
 �[36;1m  if [ "${GITHUB_EVENT_NAME}" = "workflow_call" ] && [ -n "${LANGUAGE_MATRIX}" ]; then�[0m
 �[36;1m    # Validate that language-matrix is valid JSON�[0m
 �[36;1m    if ! echo "${LANGUAGE_MATRIX}" | python3 -c "import sys, json; json.load(sys.stdin)" 2>/dev/null; then�[0m
 �[36;1m      echo "::error::Invalid language-matrix input: must be valid JSON array"�[0m
🧰 Additional context used
📓 Path-based instructions (7)
**/*.jsonnet

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use jsonnetfmt for consistent Jsonnet formatting; CI enforces this

Use jsonnetfmt formatting for Jsonnet files; CI enforces this

Files:

  • test/python/pyjited.jsonnet
**/*.{cpp,cc,cxx,h,hpp}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.{cpp,cc,cxx,h,hpp}: Use clang-format tool for all C++ code formatting (VS Code auto-formats on save); configuration defined in .clang-format with 100-character line limit and 2-space indentation
Follow clang-tidy recommendations defined in .clang-tidy

Files:

  • plugins/python/src/dyncall.cpp
  • plugins/python/src/dyncall.hpp
  • plugins/python/src/modulewrap.cpp
**/*.{hpp,cpp}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{hpp,cpp}: Use .hpp for header files, .cpp for implementation, and *_test.cpp for test files in C++
Enforce 100-character line limit and 2-space indentation in C++ code via .clang-format
Use QualifierAlignment: Right (east-const) style: int const x not const int x in C++
Use PointerAlignment: Left in C++ (pointer * attached to type, not variable name)
All C++ identifiers must use lower_case naming: namespaces, classes, structs, enums, functions, variables, parameters, members, and constants
Exception to C++ naming: template parameters use CamelCase
Exception to C++ naming: macros use UPPER_CASE
Private, protected, and constant members in C++ must have a trailing underscore (_), no trailing underscore on anything else
Use enum class preferred over plain enum in C++
Use std::shared_ptr for shared ownership, std::unique_ptr for exclusive ownership, raw pointers for non-owning references only in C++
Use functors with agent-noun pattern: ModelEvaluator evaluate_model(...) in C++
Apply .clang-tidy checks for bugprone, cert, clang-analyzer, concurrency, cppcoreguidelines, misc, modernize, performance, portability, and readability as defined in the .clang-tidy configuration file
Use phlex:: namespace for core code, phlex::experimental:: for experimental features in C++

Files:

  • plugins/python/src/dyncall.cpp
  • plugins/python/src/dyncall.hpp
  • plugins/python/src/modulewrap.cpp
plugins/python/**/*.cpp

📄 CodeRabbit inference engine (AGENTS.md)

plugins/python/**/*.cpp: Use std::runtime_error for C++ runtime failures; propagate Python exceptions via PyErr_SetString/PyErr_Format; return nullptr on error; call PyErr_Clear() when recovering in Python/C++ integration
Use manual Py_INCREF/Py_DECREF for reference counting and PyGILRAII RAII wrapper for GIL management in C++ code that interacts with Python
For GC-tracked Python types in C++: use Py_TPFLAGS_HAVE_GC, implement tp_traverse and tp_clear, call PyObject_GC_UnTrack before deallocation

Files:

  • plugins/python/src/dyncall.cpp
  • plugins/python/src/modulewrap.cpp
**/*.py

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.py: Use ruff for Python formatting and linting (configured in pyproject.toml); follow Google-style docstring conventions; use line length of 99 characters; use double quotes for strings
Use from __future__ import annotations to enable deferred evaluation of type annotations (avoids forward-reference issues; Python >=3.12)
Type hints are recommended; mypy is configured in pyproject.toml
Avoid naming Python test scripts types.py or other names that shadow standard library modules, as this causes obscure import errors
Python test scripts should follow the test structure pattern: C++ driver provides data streams, Jsonnet config wires the graph, and Python script implements algorithms

**/*.py: Enforce 99-character line limit and double quotes in Python via ruff configured in pyproject.toml
Use Google-style docstrings in Python code
Use type hints in Python code and configure mypy for type checking
Use from __future__ import annotations in Python to enable deferred evaluation of type annotations
Use PEP 8 naming in Python: CapWords for classes, snake_case for everything else
When using the read tool for Python files, always use integer values for offset and limit parameters, never float/double values

Files:

  • test/python/jited.py
  • plugins/python/python/phlex/_typing.py
test/**/*.py

📄 CodeRabbit inference engine (AGENTS.md)

Name Python test files as test_*.py, do NOT name files after stdlib modules (e.g., types.py)

Files:

  • test/python/jited.py
**/*.hpp

📄 CodeRabbit inference engine (AGENTS.md)

Avoid boolean parameters in C++ interfaces; prefer enumerations instead

Files:

  • plugins/python/src/dyncall.hpp
🧠 Learnings (1)
📚 Learning: 2026-06-18T23:48:04.336Z
Learnt from: wlav
Repo: Framework-R-D/phlex PR: 626
File: test/python/jited.py:25-25
Timestamp: 2026-06-18T23:48:04.336Z
Learning: In Phlex Python test/module files under `test/python/` (e.g., `test/python/jited.py`), treat `PHLEX_REGISTER_ALGORITHMS` as an intentional macro-based interface that mirrors the equivalent C++ macro. Do not add or change type hints for `PHLEX_REGISTER_ALGORITHMS`; it should remain untyped because it’s part of Phlex’s macro contract and Phlex internal types are not exposed to Python by design.

Applied to files:

  • test/python/jited.py
🪛 Cppcheck (2.21.0)
plugins/python/src/dyncall.cpp

[style] 15-15: The function 'from_str' is never used.

(unusedFunction)


[style] 96-96: The function 'dyncall' is never used.

(unusedFunction)

🔇 Additional comments (2)
plugins/python/python/phlex/_typing.py (1)

17-28: LGTM!

Also applies to: 50-66, 123-127

plugins/python/CMakeLists.txt (1)

10-12: LGTM!

Also applies to: 23-29

Comment thread plugins/python/src/dyncall.cpp Outdated
Comment thread plugins/python/src/dyncall.hpp
Comment thread plugins/python/src/dyncall.hpp Outdated
Comment thread plugins/python/src/modulewrap.cpp Outdated
Comment thread plugins/python/src/modulewrap.cpp Outdated
Comment thread plugins/python/src/modulewrap.cpp Outdated
Comment thread plugins/python/src/modulewrap.cpp
Comment thread test/python/CMakeLists.txt Outdated
Comment thread test/python/jited.py Outdated
Comment thread test/python/pyjited.jsonnet
@greenc-FNAL

Copy link
Copy Markdown
Contributor

@wlav A de novo review by CodeRabbit claims to have identified several correctness issues. Ignoring the naming convention complaints, could you take a look, including at the reference-counting issue in the review walkthrough rather than a diff-specific comment thread?

@wlav

wlav commented Jun 26, 2026

Copy link
Copy Markdown
Contributor Author

@greenc-FNAL: done. Mostly good stuff actually.

@greenc-FNAL

Copy link
Copy Markdown
Contributor

@coderabbitai review

Ignore/resolve outstanding naming comments: naming issues will be addressed en masse after the upcoming 0.3 release.

@coderabbitai

coderabbitai Bot commented Jun 26, 2026

Copy link
Copy Markdown
Contributor
🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

owner="Framework-R-D"
repo="phlex"
pr="626"

gh api graphql \
  -F owner="$owner" \
  -F name="$repo" \
  -F pr="$pr" \
  -f query='
query($owner: String!, $name: String!, $pr: Int!) {
  repository(owner: $owner, name: $name) {
    pullRequest(number: $pr) {
      reviewThreads(first: 100) {
        nodes {
          id
          isResolved
          isOutdated
          path
          line
          comments(first: 20) {
            nodes {
              author { login }
              body
              url
              createdAt
            }
          }
        }
      }
    }
  }
}' > /tmp/pr_threads.json

python - <<'PY'
import json
from pathlib import Path

data = json.loads(Path('/tmp/pr_threads.json').read_text())
threads = data["data"]["repository"]["pullRequest"]["reviewThreads"]["nodes"]

for i, t in enumerate(threads, 1):
    if t["isResolved"]:
        continue
    authors = {c["author"]["login"] if c["author"] else "UNKNOWN" for c in t["comments"]["nodes"]}
    if not any(a.lower().startswith("coderabbit") for a in authors):
        continue
    print("=" * 100)
    print(f"THREAD {i}")
    print(f"id       : {t['id']}")
    print(f"path     : {t['path']}")
    print(f"line     : {t['line']}")
    print(f"resolved : {t['isResolved']}")
    print(f"outdated : {t['isOutdated']}")
    for j, c in enumerate(t["comments"]["nodes"], 1):
        author = c["author"]["login"] if c["author"] else "UNKNOWN"
        body = c["body"].strip().replace("\r", "")
        print(f"\n  COMMENT {j}")
        print(f"  author : {author}")
        print(f"  url    : {c['url']}")
        print("  body:")
        for line in body.splitlines():
            print(f"    {line}")
PY

Length of output: 1868


🏁 Script executed:

#!/bin/bash
set -euo pipefail

owner="Framework-R-D"
repo="phlex"
pr="626"

gh api graphql \
  -F owner="$owner" \
  -F name="$repo" \
  -F pr="$pr" \
  -f query='
query($owner: String!, $name: String!, $pr: Int!) {
  repository(owner: $owner, name: $name) {
    pullRequest(number: $pr) {
      reviewThreads(first: 100) {
        nodes {
          id
          isResolved
          isOutdated
          path
          line
          comments(first: 10) {
            nodes {
              author { login }
              body
              url
            }
          }
        }
      }
    }
  }
}' | python - <<'PY'
import json, sys

data = json.load(sys.stdin)
threads = data["data"]["repository"]["pullRequest"]["reviewThreads"]["nodes"]

found = 0
for t in threads:
    if t["isResolved"]:
        continue
    comments = t["comments"]["nodes"]
    authors = [(c["author"]["login"] if c["author"] else "UNKNOWN") for c in comments]
    if not any(a.lower().startswith("coderabbit") for a in authors):
        continue

    found += 1
    print("---")
    print(f"thread_id: {t['id']}")
    print(f"path: {t['path']}")
    print(f"line: {t['line']}")
    print(f"outdated: {t['isOutdated']}")
    for idx, c in enumerate(comments, 1):
        author = c["author"]["login"] if c["author"] else "UNKNOWN"
        body = " ".join(c["body"].split())
        if len(body) > 300:
            body = body[:300] + "..."
        print(f"comment_{idx}_author: {author}")
        print(f"comment_{idx}_url: {c['url']}")
        print(f"comment_{idx}_body: {body}")

if found == 0:
    print("NO_UNRESOLVED_CODERABBIT_THREADS")
PY

Length of output: 2682


🏁 Script executed:

#!/bin/bash
set -euo pipefail

owner="Framework-R-D"
repo="phlex"
pr="626"

echo "== gh version =="
gh --version || true

echo
echo "== gh auth status =="
gh auth status || true

echo
echo "== graphql raw query =="
set +e
gh api graphql \
  -F owner="$owner" \
  -F name="$repo" \
  -F pr="$pr" \
  -f query='
query($owner: String!, $name: String!, $pr: Int!) {
  repository(owner: $owner, name: $name) {
    pullRequest(number: $pr) {
      reviewThreads(first: 20) {
        nodes {
          id
          isResolved
          path
          line
        }
      }
    }
  }
}' > /tmp/gh_graphql_stdout.txt 2> /tmp/gh_graphql_stderr.txt
status=$?
set -e

echo "graphql_exit_status=$status"
echo "--- graphql stdout ---"
cat /tmp/gh_graphql_stdout.txt || true
echo
echo "--- graphql stderr ---"
cat /tmp/gh_graphql_stderr.txt || true

echo
echo "== gh pr view fallback =="
set +e
gh pr view "https://github.com/${owner}/${repo}/pull/${pr}" --json number,title,reviewDecision,reviews,comments > /tmp/gh_pr_view.json 2> /tmp/gh_pr_view_stderr.txt
status2=$?
set -e
echo "pr_view_exit_status=$status2"
echo "--- pr view stderr ---"
cat /tmp/gh_pr_view_stderr.txt || true
echo "--- pr view summary ---"
python - <<'PY'
import json
from pathlib import Path
p = Path('/tmp/gh_pr_view.json')
if not p.exists() or not p.read_text().strip():
    print("NO_PR_VIEW_JSON")
else:
    data = json.loads(p.read_text())
    print("number:", data.get("number"))
    print("title:", data.get("title"))
    print("reviewDecision:", data.get("reviewDecision"))
    print("reviews:", len(data.get("reviews", [])))
    print("comments:", len(data.get("comments", [])))
    for c in data.get("comments", [])[:10]:
        author = (c.get("author") or {}).get("login")
        body = " ".join((c.get("body") or "").split())
        print(f"- author={author} body={body[:220]}")
PY

Length of output: 7079



@greenc-FNAL: Got it. I checked the PR review threads I could retrieve, and the CodeRabbit review threads in that set are already resolved, so there isn’t an obvious outstanding naming-only thread for me to close selectively.

I’ll treat naming nits as deferred for now and focus this pass on substantive issues only: correctness, safety, refcounting/lifetime, API behavior, and test/build-impact.

✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
plugins/python/src/modulewrap.cpp (3)

681-690: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Propagate list element conversion errors instead of returning partial vectors.

The list branch pushes the converted value, clears any Python error, breaks, and then returns the partially-filled vector. A single bad element can silently corrupt the graph data.

Suggested fix
       Py_ssize_t total = PyList_Size(pyobj);                                                       
       vec->reserve(total);                                                                         
       for (Py_ssize_t i = 0; i < total; ++i) {                                                     
         PyObject* item = PyList_GetItem(pyobj, i);                                                 
-        vec->push_back(static_cast<cpptype>(frompy(item)));                                        
-        if (PyErr_Occurred()) {                                                                    
-          PyErr_Clear();                                                                           
-          break;                                                                                   
+        cpptype value = static_cast<cpptype>(frompy(item));                                        
+        std::string msg;                                                                           
+        if (msg_from_py_error(msg, true)) {                                                        
+          Py_DECREF(pyobj);                                                                        
+          throw std::runtime_error("List conversion error for type " `#name` ": " + msg);            
         }                                                                                          
+        vec->push_back(value);                                                                     
       }                                                                                            
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@plugins/python/src/modulewrap.cpp` around lines 681 - 690, The PyList_Check
branch in modulewrap.cpp is swallowing element conversion failures and returning
a partially filled vector, so update this path to stop on the first bad item and
propagate the Python error instead of clearing it. In the list conversion loop,
use frompy(item) only after confirming the conversion succeeded, and if
PyErr_Occurred() becomes true, do not continue building vec; let the error
bubble out from the list-handling logic that wraps PyList_Check.

421-426: 🩺 Stability & Availability | 🟠 Major

plugins/python/src/modulewrap.cpp:421-479 — Clear the missing-__annotations__ error before falling back to _sig.

PyObject_GetAttr(callable, sann) leaves AttributeError pending when __annotations__ is absent. If the Numba _sig path succeeds, annotations_to_strings() still returns true with that exception set, which can surface later as a CPython failure. Clear the missing-attribute error before trying _sig, and keep "unknown annotation formatting" for the remaining failure cases.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@plugins/python/src/modulewrap.cpp` around lines 421 - 426, The fallback logic
in modulewrap.cpp’s annotation handling leaves a pending AttributeError after
PyObject_GetAttr(callable, sann) fails, which can leak through even when the
_sig path succeeds. Update the annotations_to_strings flow to clear the
missing-__annotations__ error before attempting the Numba _sig fallback, and
keep the existing "unknown annotation formatting" message only for the cases
where both annotation lookup and signature fallback fail.

617-631: 🎯 Functional Correctness | 🟠 Major

Handle null vector conversion without returning NULL. PyObject_CallFunctionObjArgs treats NULL as the end of the variadic list, so dcarg{nullptr} will truncate the Python call; it can also lead to Py_DECREF(nullptr) in decref_all(). Use Py_None for intentional empties and throw on PyArray_SimpleNewFromData/lifeline allocation failures. plugins/python/src/modulewrap.cpp:617-631

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@plugins/python/src/modulewrap.cpp` around lines 617 - 631, The null-vector
path in the conversion helper returns dcarg{nullptr}, which can be misread by
PyObject_CallFunctionObjArgs and later trigger decref issues in decref_all().
Update the conversion logic in modulewrap.cpp’s numpy view creation path so
intentional empty values are represented with Py_None instead of NULL, and make
PyArray_SimpleNewFromData and any lifeline allocation failures raise an
exception rather than returning a null argument wrapper.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@plugins/python/src/modulewrap.cpp`:
- Line 1048: The JIT callback wiring in insert_input_converters and the related
output setup still allows collection annotations to reach the libffi/Numba path,
which can pass PyObject* values into a cfunc before converters reject them. Add
an early guard in the JIT path, before callbacks are wired, to reject collection
types such as ndarray and list for both inputs and outputs, and make sure
jit_callback and the input/output converter setup bail out before calling
dcarg::from_str or selecting v*_to_py converters for these annotations.

In `@test/python/adder.py`:
- Around line 59-64: The negative-path check in the test for m.transform should
explicitly fail if no TypeError is raised, since it currently only validates the
exception message and can still pass when the missing-output-suffix validation
regresses. Update the try/except around m.transform(int_adder,
input_family=config["input"]) to include an else branch that raises an assertion
failure, keeping the existing TypeError message check intact. Use the
m.transform call and the TypeError handler in adder.py as the anchor points for
the fix.

---

Outside diff comments:
In `@plugins/python/src/modulewrap.cpp`:
- Around line 681-690: The PyList_Check branch in modulewrap.cpp is swallowing
element conversion failures and returning a partially filled vector, so update
this path to stop on the first bad item and propagate the Python error instead
of clearing it. In the list conversion loop, use frompy(item) only after
confirming the conversion succeeded, and if PyErr_Occurred() becomes true, do
not continue building vec; let the error bubble out from the list-handling logic
that wraps PyList_Check.
- Around line 421-426: The fallback logic in modulewrap.cpp’s annotation
handling leaves a pending AttributeError after PyObject_GetAttr(callable, sann)
fails, which can leak through even when the _sig path succeeds. Update the
annotations_to_strings flow to clear the missing-__annotations__ error before
attempting the Numba _sig fallback, and keep the existing "unknown annotation
formatting" message only for the cases where both annotation lookup and
signature fallback fail.
- Around line 617-631: The null-vector path in the conversion helper returns
dcarg{nullptr}, which can be misread by PyObject_CallFunctionObjArgs and later
trigger decref issues in decref_all(). Update the conversion logic in
modulewrap.cpp’s numpy view creation path so intentional empty values are
represented with Py_None instead of NULL, and make PyArray_SimpleNewFromData and
any lifeline allocation failures raise an exception rather than returning a null
argument wrapper.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: ae868e6a-cefb-495d-9d83-6405f2a303e1

📥 Commits

Reviewing files that changed from the base of the PR and between 025390c and 5429b2d.

📒 Files selected for processing (6)
  • plugins/python/src/dyncall.cpp
  • plugins/python/src/dyncall.hpp
  • plugins/python/src/modulewrap.cpp
  • test/python/CMakeLists.txt
  • test/python/adder.py
  • test/python/jited.py
📜 Review details
⏰ Context from checks skipped due to timeout. (1)
  • GitHub Check: clang-tidy-check
⚠️ CI failures not shown inline (17)

GitHub Actions: wlav checking CMake format / 0_cmake-format-check.txt: wlav checking CMake format

Conclusion: failure

View job details

##[group]Run REPO_NAME="${REPO##*/}"
 �[36;1mREPO_NAME="${REPO##*/}"�[0m
 �[36;1mif [ "success" = 'success' ]; then�[0m
 �[36;1m  echo "✅ All CMake files are properly formatted."�[0m
 �[36;1melse�[0m
 �[36;1m  echo "::error::Found files with formatting issues."�[0m

GitHub Actions: wlav checking CMake format / cmake-format-check: wlav checking CMake format

Conclusion: failure

View job details

##[group]Run REPO_NAME="${REPO##*/}"
 �[36;1mREPO_NAME="${REPO##*/}"�[0m
 �[36;1mif [ "success" = 'success' ]; then�[0m
 �[36;1m  echo "✅ All CMake files are properly formatted."�[0m
 �[36;1melse�[0m
 �[36;1m  echo "::error::Found files with formatting issues."�[0m

GitHub Actions: wlav checking Jsonnet format / jsonnet-format-check: wlav checking Jsonnet format

Conclusion: failure

View job details

##[group]Run REPO_NAME="${REPO##*/}"
 �[36;1mREPO_NAME="${REPO##*/}"�[0m
 �[36;1mif [ "success" = 'success' ]; then�[0m
 �[36;1m  echo "✅ Jsonnet formatting check passed."�[0m
 �[36;1melse�[0m
 �[36;1m  echo "::error::Jsonnet formatting issues found. Please review the output above for details."�[0m

GitHub Actions: wlav checking C++ code format / 0_clang-format-check.txt: wlav checking C++ code format

Conclusion: failure

View job details

##[group]Run REPO_NAME="${REPO##*/}"
 �[36;1mREPO_NAME="${REPO##*/}"�[0m
 �[36;1mif [ "success" = 'success' ]; then�[0m
 �[36;1m  echo "✅ clang-format check passed."�[0m
 �[36;1melse�[0m
 �[36;1m  echo "::error::clang-format check failed. Please review the output above for details."�[0m

GitHub Actions: wlav checking C++ code format / clang-format-check: wlav checking C++ code format

Conclusion: failure

View job details

##[group]Run REPO_NAME="${REPO##*/}"
 �[36;1mREPO_NAME="${REPO##*/}"�[0m
 �[36;1mif [ "success" = 'success' ]; then�[0m
 �[36;1m  echo "✅ clang-format check passed."�[0m
 �[36;1melse�[0m
 �[36;1m  echo "::error::clang-format check failed. Please review the output above for details."�[0m

GitHub Actions: wlav checking Jsonnet format / 0_jsonnet-format-check.txt: wlav checking Jsonnet format

Conclusion: failure

View job details

##[group]Run REPO_NAME="${REPO##*/}"
 �[36;1mREPO_NAME="${REPO##*/}"�[0m
 �[36;1mif [ "success" = 'success' ]; then�[0m
 �[36;1m  echo "✅ Jsonnet formatting check passed."�[0m
 �[36;1melse�[0m
 �[36;1m  echo "::error::Jsonnet formatting issues found. Please review the output above for details."�[0m

GitHub Actions: wlav checking Python code / scripts-test: wlav checking Python code

Conclusion: failure

View job details

##[group]Run codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f
 with:
   files: coverage-scripts.xml
   flags: scripts
   name: phlex-scripts-coverage
   fail_ci_if_error: false
   verbose: true
   root_dir: phlex-src
   disable_file_fixes: false
   disable_search: false
   disable_safe_directory: false
   disable_telem: false
   dry_run: false
   git_service: github
   gcov_executable: gcov
   handle_no_reports_found: false
   recurse_submodules: false
   run_command: upload-coverage
   skip_validation: false
   use_legacy_upload_endpoint: false
   use_oidc: false
   use_pypi: false
   version: latest
 env:
   CODECOV_***REDACTED*** /home/runner/work/_temp/uv-python-dir
   UV_CACHE_DIR: /home/runner/work/_temp/setup-uv-cache
 ##[endgroup]
 ##[group]Run missing_deps=""
 �[36;1mmissing_deps=""�[0m
 �[36;1m�[0m
 �[36;1m# Check for always-required commands�[0m
 �[36;1mfor cmd in bash git curl; do�[0m
 �[36;1m  if ! command -v "$cmd" >/dev/null 2>&1; then�[0m
 �[36;1m    missing_deps="$missing_deps $cmd"�[0m
 �[36;1m  fi�[0m
 �[36;1mdone�[0m
 �[36;1m�[0m
 �[36;1m# Check for gpg only if validation is not being skipped�[0m
 �[36;1mif [ "$INPUT_SKIP_VALIDATION" != "true" ]; then�[0m
 �[36;1m  if ! command -v gpg >/dev/null 2>&1; then�[0m
 �[36;1m    missing_deps="$missing_deps gpg"�[0m
 �[36;1m  fi�[0m
 �[36;1mfi�[0m
 �[36;1m�[0m
 �[36;1m# Report missing required dependencies�[0m
 �[36;1mif [ -n "$missing_deps" ]; then�[0m
 �[36;1m  echo "Error: The following required dependencies are missing:$missing_deps"�[0m
 �[36;1m  echo "Please install these dependencies before using this action."�[0m
 �[36;1m  exit 1�[0m
 �[36;1mfi�[0m
 �[36;1m�[0m
 �[36;1mecho "All required system dependencies are available."�[0m
 shell: /usr/bin/sh -e {0}
 env:
   CODECOV_***REDACTED*** /home/runner/work/_temp/uv-python-dir
   UV_CACHE_DIR: /home/runner/work/_temp/setup-uv-cache
   INPUT_SKIP_VALIDATION: false
 ##[endgroup]
 All required system dependencies are available.
 ##[grou...

GitHub Actions: wlav checking Python code / python-check: wlav checking Python code

Conclusion: failure

View job details

##[group]Run REPO_NAME="${REPO##*/}"
 �[36;1mREPO_NAME="${REPO##*/}"�[0m
 �[36;1mif [ "success" = 'success' ] && [ "success" = 'success' ]; then�[0m
 �[36;1m  echo "✅ Python checks passed."�[0m
 �[36;1melse�[0m
 �[36;1m  echo "::error::Python checks failed. Comment '@${REPO_NAME}bot python-fix' on the PR to attempt auto-fix."�[0m

GitHub Actions: wlav checking Python code / 1_python-check.txt: wlav checking Python code

Conclusion: failure

View job details

##[group]Run REPO_NAME="${REPO##*/}"
 �[36;1mREPO_NAME="${REPO##*/}"�[0m
 �[36;1mif [ "success" = 'success' ] && [ "success" = 'success' ]; then�[0m
 �[36;1m  echo "✅ Python checks passed."�[0m
 �[36;1melse�[0m
 �[36;1m  echo "::error::Python checks failed. Comment '@${REPO_NAME}bot python-fix' on the PR to attempt auto-fix."�[0m

GitHub Actions: wlav checking Python code / 0_scripts-test.txt: wlav checking Python code

Conclusion: failure

View job details

estMainSarifMode::test_new_alert_returns_zero_and_writes_comment PASSED [ 23%]
 scripts/test/test_check_codeql_alerts.py::TestMainSarifMode::test_absent_alert_returns_zero_and_writes_comment PASSED [ 24%]
 scripts/test/test_check_codeql_alerts.py::TestMainSarifMode::test_no_alerts_returns_zero_no_comment PASSED [ 24%]
 scripts/test/test_check_codeql_alerts.py::TestMainSarifMode::test_below_threshold_alert_not_reported PASSED [ 24%]
 scripts/test/test_check_codeql_alerts.py::TestMainSarifMode::test_missing_sarif_exits_nonzero PASSED [ 24%]
 scripts/test/test_check_codeql_alerts.py::TestMainSarifMode::test_github_output_written PASSED [ 24%]
 scripts/test/test_check_codeql_alerts.py::TestMainSarifMode::test_github_output_false_when_no_alerts PASSED [ 25%]
 scripts/test/test_check_codeql_alerts.py::TestMainSarifMode::test_directory_of_sarif_files PASSED [ 25%]
 scripts/test/test_check_codeql_alerts.py::TestMainSarifMode::test_sarif_mode_pr_ref_produces_filtered_url PASSED [ 25%]
 scripts/test/test_check_codeql_alerts.py::TestMainSarifMode::test_non_integer_pr_ref_no_filtered_url PASSED [ 25%]
 scripts/test/test_check_codeql_alerts.py::TestMainApiMode::test_api_mode_new_alert PASSED [ 25%]
 scripts/test/test_check_codeql_alerts.py::TestMainApiMode::test_api_mode_min_level_filtering PASSED [ 26%]
 scripts/test/test_check_codeql_alerts.py::TestMainApiMode::test_api_mode_github_api_error_exits_2 PASSED [ 26%]
 scripts/test/test_check_codeql_alerts.py::TestMainApiMode::test_api_mode_missing_github_repository_exits_2 PASSED [ 26%]
 scripts/test/test_check_codeql_alerts.py::TestMainApiMode::test_api_mode_skipped_when_sarif_has_baseline PASSED [ 26%]
 scripts/test/test_check_codeql_alerts.py::TestMainApiModeWithPrRef::test_api_mode_pr_ref_produces_filtered_url PASSED [ 27%]
 scripts/test/test_check_codeql_alerts.py::TestMainEntrypoint::test_entrypoint_no_alerts_exits_zero PASSED [ 27%]
 scripts/test/test_clang_tidy_check_summary.py::TestLoadDiagnostics::test_reads_from_file...

GitHub Actions: wlav building and testing Framework-R-D/phlex / build (gcc, none): wlav building and testing Framework-R-D/phlex

Conclusion: failure

View job details

�[36;1mecho "::group::Running ctest"�[0m
 �[36;1mif ctest --progress --output-on-failure -j "$(nproc)"; then�[0m
 �[36;1m  echo "::endgroup::"�[0m
 �[36;1m  echo "✅ All tests passed."�[0m
 �[36;1melse�[0m
 �[36;1m  echo "::endgroup::"�[0m
 �[36;1m  echo "::error:: Some tests failed."�[0m

GitHub Actions: wlav building and testing Framework-R-D/phlex / 1_build (gcc, none).txt: wlav building and testing Framework-R-D/phlex

Conclusion: failure

View job details

�[36;1mecho "::group::Running ctest"�[0m
 �[36;1mif ctest --progress --output-on-failure -j "$(nproc)"; then�[0m
 �[36;1m  echo "::endgroup::"�[0m
 �[36;1m  echo "✅ All tests passed."�[0m
 �[36;1melse�[0m
 �[36;1m  echo "::endgroup::"�[0m
 �[36;1m  echo "::error:: Some tests failed."�[0m

GitHub Actions: wlav running code coverage / coverage: wlav running code coverage

Conclusion: failure

View job details

�[36;1mecho "::group::Running ctest for coverage"�[0m
 �[36;1mif ctest --progress --output-on-failure -j "$(nproc)"; then�[0m
 �[36;1m  echo "::endgroup::"�[0m
 �[36;1m  echo "✅ All tests passed."�[0m
 �[36;1melse�[0m
 �[36;1m  echo "::endgroup::"�[0m
 �[36;1m  echo "::error::Some tests failed."�[0m

GitHub Actions: wlav running code coverage / 2_coverage.txt: wlav running code coverage

Conclusion: failure

View job details

�[36;1mecho "::group::Running ctest for coverage"�[0m
 �[36;1mif ctest --progress --output-on-failure -j "$(nproc)"; then�[0m
 �[36;1m  echo "::endgroup::"�[0m
 �[36;1m  echo "✅ All tests passed."�[0m
 �[36;1melse�[0m
 �[36;1m  echo "::endgroup::"�[0m
 �[36;1m  echo "::error::Some tests failed."�[0m

GitHub Actions: wlav running code coverage / coverage: wlav running code coverage

Conclusion: failure

View job details

�[36;1mecho "::group::Running coverage-llvm target"�[0m
 �[36;1mif cmake --build . --target coverage-llvm -v; then�[0m
 �[36;1m  echo "::endgroup::"�[0m
 �[36;1m  echo "✅ Clang coverage report generation succeeded."�[0m
 �[36;1melse�[0m
 �[36;1m  echo "::endgroup::"�[0m
 �[36;1m  echo "::error::Clang coverage report generation failed."�[0m

GitHub Actions: CodeQL Analysis / determine-languages: Initial Numba support

Conclusion: failure

View job details

##[group]Run # If detection was skipped, use all languages or the provided language-matrix
 �[36;1m# If detection was skipped, use all languages or the provided language-matrix�[0m
 �[36;1mif [ "${SKIP_DETECTION}" = "true" ]; then�[0m
 �[36;1m  if [ "${GITHUB_EVENT_NAME}" = "workflow_call" ] && [ -n "${LANGUAGE_MATRIX}" ]; then�[0m
 �[36;1m    # Validate that language-matrix is valid JSON�[0m
 �[36;1m    if ! echo "${LANGUAGE_MATRIX}" | python3 -c "import sys, json; json.load(sys.stdin)" 2>/dev/null; then�[0m
 �[36;1m      echo "::error::Invalid language-matrix input: must be valid JSON array"�[0m

GitHub Actions: CodeQL Analysis / 3_determine-languages.txt: Initial Numba support

Conclusion: failure

View job details

##[group]Run # If detection was skipped, use all languages or the provided language-matrix
 �[36;1m# If detection was skipped, use all languages or the provided language-matrix�[0m
 �[36;1mif [ "${SKIP_DETECTION}" = "true" ]; then�[0m
 �[36;1m  if [ "${GITHUB_EVENT_NAME}" = "workflow_call" ] && [ -n "${LANGUAGE_MATRIX}" ]; then�[0m
 �[36;1m    # Validate that language-matrix is valid JSON�[0m
 �[36;1m    if ! echo "${LANGUAGE_MATRIX}" | python3 -c "import sys, json; json.load(sys.stdin)" 2>/dev/null; then�[0m
 �[36;1m      echo "::error::Invalid language-matrix input: must be valid JSON array"�[0m
🧰 Additional context used
📓 Path-based instructions (6)
**/*.py

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.py: Use ruff for Python formatting and linting (configured in pyproject.toml); follow Google-style docstring conventions; use line length of 99 characters; use double quotes for strings
Use from __future__ import annotations to enable deferred evaluation of type annotations (avoids forward-reference issues; Python >=3.12)
Type hints are recommended; mypy is configured in pyproject.toml
Avoid naming Python test scripts types.py or other names that shadow standard library modules, as this causes obscure import errors
Python test scripts should follow the test structure pattern: C++ driver provides data streams, Jsonnet config wires the graph, and Python script implements algorithms

**/*.py: Enforce 99-character line limit and double quotes in Python via ruff configured in pyproject.toml
Use Google-style docstrings in Python code
Use type hints in Python code and configure mypy for type checking
Use from __future__ import annotations in Python to enable deferred evaluation of type annotations
Use PEP 8 naming in Python: CapWords for classes, snake_case for everything else
When using the read tool for Python files, always use integer values for offset and limit parameters, never float/double values

Files:

  • test/python/adder.py
  • test/python/jited.py
test/**/*.py

📄 CodeRabbit inference engine (AGENTS.md)

Name Python test files as test_*.py, do NOT name files after stdlib modules (e.g., types.py)

Files:

  • test/python/adder.py
  • test/python/jited.py
**/*.{cpp,cc,cxx,h,hpp}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.{cpp,cc,cxx,h,hpp}: Use clang-format tool for all C++ code formatting (VS Code auto-formats on save); configuration defined in .clang-format with 100-character line limit and 2-space indentation
Follow clang-tidy recommendations defined in .clang-tidy

Files:

  • plugins/python/src/dyncall.hpp
  • plugins/python/src/dyncall.cpp
  • plugins/python/src/modulewrap.cpp
**/*.{hpp,cpp}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{hpp,cpp}: Use .hpp for header files, .cpp for implementation, and *_test.cpp for test files in C++
Enforce 100-character line limit and 2-space indentation in C++ code via .clang-format
Use QualifierAlignment: Right (east-const) style: int const x not const int x in C++
Use PointerAlignment: Left in C++ (pointer * attached to type, not variable name)
All C++ identifiers must use lower_case naming: namespaces, classes, structs, enums, functions, variables, parameters, members, and constants
Exception to C++ naming: template parameters use CamelCase
Exception to C++ naming: macros use UPPER_CASE
Private, protected, and constant members in C++ must have a trailing underscore (_), no trailing underscore on anything else
Use enum class preferred over plain enum in C++
Use std::shared_ptr for shared ownership, std::unique_ptr for exclusive ownership, raw pointers for non-owning references only in C++
Use functors with agent-noun pattern: ModelEvaluator evaluate_model(...) in C++
Apply .clang-tidy checks for bugprone, cert, clang-analyzer, concurrency, cppcoreguidelines, misc, modernize, performance, portability, and readability as defined in the .clang-tidy configuration file
Use phlex:: namespace for core code, phlex::experimental:: for experimental features in C++

Files:

  • plugins/python/src/dyncall.hpp
  • plugins/python/src/dyncall.cpp
  • plugins/python/src/modulewrap.cpp
**/*.hpp

📄 CodeRabbit inference engine (AGENTS.md)

Avoid boolean parameters in C++ interfaces; prefer enumerations instead

Files:

  • plugins/python/src/dyncall.hpp
plugins/python/**/*.cpp

📄 CodeRabbit inference engine (AGENTS.md)

plugins/python/**/*.cpp: Use std::runtime_error for C++ runtime failures; propagate Python exceptions via PyErr_SetString/PyErr_Format; return nullptr on error; call PyErr_Clear() when recovering in Python/C++ integration
Use manual Py_INCREF/Py_DECREF for reference counting and PyGILRAII RAII wrapper for GIL management in C++ code that interacts with Python
For GC-tracked Python types in C++: use Py_TPFLAGS_HAVE_GC, implement tp_traverse and tp_clear, call PyObject_GC_UnTrack before deallocation

Files:

  • plugins/python/src/dyncall.cpp
  • plugins/python/src/modulewrap.cpp
🧠 Learnings (1)
📚 Learning: 2026-06-18T23:48:04.336Z
Learnt from: wlav
Repo: Framework-R-D/phlex PR: 626
File: test/python/jited.py:25-25
Timestamp: 2026-06-18T23:48:04.336Z
Learning: In Phlex Python test/module files under `test/python/` (e.g., `test/python/jited.py`), treat `PHLEX_REGISTER_ALGORITHMS` as an intentional macro-based interface that mirrors the equivalent C++ macro. Do not add or change type hints for `PHLEX_REGISTER_ALGORITHMS`; it should remain untyped because it’s part of Phlex’s macro contract and Phlex internal types are not exposed to Python by design.

Applied to files:

  • test/python/adder.py
  • test/python/jited.py
🔇 Additional comments (4)
test/python/CMakeLists.txt (1)

88-90: LGTM!

test/python/jited.py (1)

8-8: LGTM!

Also applies to: 48-56

plugins/python/src/dyncall.hpp (1)

23-23: LGTM!

Also applies to: 40-54, 78-82, 87-90, 92-94

plugins/python/src/dyncall.cpp (1)

95-129: LGTM!

Comment thread plugins/python/src/modulewrap.cpp
Comment thread test/python/adder.py
@github-actions

Copy link
Copy Markdown
Contributor

Clang-Tidy Check Results

Found 5428 issue(s); none are newly introduced by this patch.

All issues by check:

  • readability-identifier-naming: 2066
  • readability-redundant-member-init: 1258
  • portability-template-virtual-member-function: 563
  • performance-unnecessary-value-param: 462
  • readability-avoid-const-params-in-decls: 269
  • modernize-pass-by-value: 206
  • readability-braces-around-statements: 118
  • modernize-use-designated-initializers: 86
  • readability-convert-member-functions-to-static: 80
  • readability-const-return-type: 50
  • modernize-use-auto: 28
  • readability-redundant-control-flow: 23
  • readability-qualified-auto: 21
  • modernize-use-using: 19
  • modernize-concat-nested-namespaces: 17
  • readability-math-missing-parentheses: 16
  • modernize-use-equals-default: 15
  • modernize-avoid-c-arrays: 15
  • readability-static-definition-in-anonymous-namespace: 14
  • bugprone-branch-clone: 12
  • readability-function-size: 12
  • modernize-return-braced-init-list: 10
  • readability-isolate-declaration: 8
  • cppcoreguidelines-special-member-functions: 7
  • readability-container-size-empty: 7
  • modernize-use-starts-ends-with: 6
  • readability-redundant-access-specifiers: 5
  • modernize-use-ranges: 5
  • readability-redundant-casting: 5
  • readability-container-contains: 5
  • readability-inconsistent-declaration-parameter-name: 5
  • modernize-use-std-numbers: 3
  • readability-else-after-return: 2
  • modernize-use-integer-sign-comparison: 2
  • performance-move-const-arg: 1
  • readability-redundant-string-init: 1
  • modernize-use-emplace: 1
  • readability-simplify-boolean-expr: 1
  • readability-use-anyofallof: 1
  • modernize-redundant-void-arg: 1
  • modernize-make-shared: 1
  • performance-avoid-endl: 1

See inline comments for details. Comment @phlexbot tidy-fix to auto-fix.

@github-actions

Copy link
Copy Markdown
Contributor

Clang-Tidy Check Results

Found 5436 issue(s); none are newly introduced by this patch.

All issues by check:

  • readability-identifier-naming: 2066
  • readability-redundant-member-init: 1258
  • portability-template-virtual-member-function: 563
  • performance-unnecessary-value-param: 462
  • readability-avoid-const-params-in-decls: 269
  • modernize-pass-by-value: 206
  • readability-braces-around-statements: 118
  • modernize-use-designated-initializers: 86
  • readability-convert-member-functions-to-static: 80
  • readability-const-return-type: 50
  • modernize-use-auto: 28
  • readability-redundant-control-flow: 23
  • readability-qualified-auto: 21
  • modernize-use-using: 19
  • modernize-concat-nested-namespaces: 17
  • readability-math-missing-parentheses: 16
  • modernize-use-equals-default: 15
  • modernize-avoid-c-arrays: 15
  • readability-static-definition-in-anonymous-namespace: 14
  • readability-function-size: 12
  • bugprone-branch-clone: 12
  • modernize-return-braced-init-list: 10
  • readability-isolate-declaration: 8
  • modernize-use-starts-ends-with: 8
  • cppcoreguidelines-special-member-functions: 7
  • readability-container-size-empty: 7
  • bugprone-throw-keyword-missing: 6
  • readability-inconsistent-declaration-parameter-name: 5
  • readability-redundant-casting: 5
  • readability-container-contains: 5
  • modernize-use-ranges: 5
  • readability-redundant-access-specifiers: 5
  • modernize-use-std-numbers: 3
  • readability-else-after-return: 2
  • modernize-use-integer-sign-comparison: 2
  • readability-redundant-string-init: 1
  • modernize-use-emplace: 1
  • readability-simplify-boolean-expr: 1
  • readability-use-anyofallof: 1
  • performance-move-const-arg: 1
  • modernize-redundant-void-arg: 1
  • modernize-make-shared: 1
  • performance-avoid-endl: 1

See inline comments for details. Comment @phlexbot tidy-fix to auto-fix.

@knoepfel knoepfel merged commit 7e024cc into Framework-R-D:main Jun 27, 2026
40 checks passed
knoepfel added a commit to Framework-R-D/phlex-spack-recipes that referenced this pull request Jun 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants